#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <errno.h>
 
#include "dns.h"
 
extern int res_query();
extern int res_search();
extern int errno;
extern int h_errno;
 
static unsigned short getshort(unsigned char *c) 
{ 
	unsigned short u; 
	u = c[0]; 
	return (u << 8) + c[1]; 
}
 
static union { 
			HEADER hdr; 
			unsigned char buf[PACKETSZ]; 
} response;

static int responselen;
static unsigned char *responseend;
static unsigned char *responsepos;
static int numanswers;
static char name[MAXDNAME];
unsigned short pref;
 
int dns_resolve(char *domain,int type)
{
  int n;
  int i;
  errno=0;
  if(NULL == domain)
          return -1;

  responselen = res_search(domain,C_IN,type,response.buf,sizeof(response));

  if(responselen <= 0)
          return -1;
  if(responselen >= sizeof(response))
          responselen = sizeof(response);
  responseend = response.buf + responselen;
  responsepos = response.buf + sizeof(HEADER);
  n = ntohs(response.hdr.qdcount);
  while(n-->0)
  {
          i = dn_expand(response.buf,responseend,responsepos,name,MAXDNAME);
          responsepos += i;
          i = responseend - responsepos;
          if(i < QFIXEDSZ) 
			  return -1;

          responsepos += QFIXEDSZ;
  }
  numanswers = ntohs(response.hdr.ancount);
  return numanswers;
}
 
int dns_findmx(int wanttype)
{
  unsigned short rrtype;
  unsigned short rrdlen;
  int i;
 
  if(numanswers <=0) 
	  return DNS_MSG_END;
  numanswers--;
  if(responsepos == responseend) 
	  return -1;

  i = dn_expand(response.buf,responseend,responsepos,name,MAXDNAME);

  if(i < 0) 
	  return -1;
  responsepos += i;
  i = responseend - responsepos;
  if(i < 10) 
	  return -1;
  rrtype = getshort(responsepos);
  rrdlen = getshort(responsepos + 8);
  responsepos += 10;
  if(rrtype == wanttype)
  {
          if(rrdlen < 3)
                  return -1;
          pref = (responsepos[0] << 8) + responsepos[1];
          memset(name,0,MAXDNAME);
          if(dn_expand(response.buf,responseend,responsepos + 2,name,MAXDNAME) < 0)
                  return -1;
          responsepos += rrdlen;
          return strlen(name);
  }
  responsepos += rrdlen;
  return 0;
}
 
void dns_init()
{
  res_init();
  memset(name,0,MAXDNAME);
}
 
int dns_get_mxrr(unsigned short *p,unsigned char *dn,unsigned int len)
{
  *p = pref;
  strncpy(dn,name,len);
  if(len < (strlen(name)+1))
          return -1;
  return 0;
}
 
int main(int argc, char *argv[])
{
    char dname[MAXDNAME];
    int i;
    unsigned short p;

	dns_init();

	if(argc!=2)
    {
            fprintf(stderr,"bad argument\n");
            exit(-1);
    }

	i = dns_mx_query(argv[1]);
    if(i<0)
    {
            fprintf(stderr,"err\n");
            return 0;
    }
    printf("pref\tdomain name\n");

	foreach_mxrr(p,dname)
    {
            printf("%d\t%s\n",p,dname);
    }
    return 0;
 }
